package com.nut.spp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nut.spp.api.req.ClientLoginReq;
import com.nut.spp.api.req.MemberQueryReq;
import com.nut.spp.api.req.UpdatePasswordReq;
import com.nut.spp.common.Constants;
import com.nut.spp.common.FailMessage;
import com.nut.spp.common.Holder;
import com.nut.spp.common.Result;
import com.nut.spp.config.RsaProperties;
import com.nut.spp.entity.Member;
import com.nut.spp.entity.MemberInviteLog;
import com.nut.spp.entity.MemberLoginLog;
import com.nut.spp.interceptor.ClientJwt;
import com.nut.spp.interceptor.JwtTokenUtil;
import com.nut.spp.jbb.JbbService;
import com.nut.spp.mapper.MemberCouponMapper;
import com.nut.spp.mapper.MemberInviteLogMapper;
import com.nut.spp.mapper.MemberLoginLogMapper;
import com.nut.spp.mapper.MemberMapper;
import com.nut.spp.service.MemberCouponService;
import com.nut.spp.service.MemberService;
import com.nut.spp.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private JbbService jbbService;

    @Autowired
    private MemberCouponService memberCouponService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private MemberCouponMapper memberCouponMapper;

    @Autowired
    private MemberLoginLogMapper memberLoginLogMapper;

    @Autowired
    private MemberInviteLogMapper memberInviteLogMapper;

    @Override
    public Result<IPage<Member>> listPage(MemberQueryReq req) {
        IPage<Member> list = memberMapper.listPage(req.newPage(), req.getName(), req.getMobile(), req.getStatus());
        return Result.ok(list);
    }

    @Override
    public Result<Member> getById(Long memberId) {

        Member member = memberMapper.selectById(memberId);
        if (member == null) {
            return Result.fail("找不到人员信息");
        }

        return Result.ok(member);
    }

    @Override
    public Result add(Member member) {

        String mobile = member.getMobile();
        if (StringTool.isEmpty(mobile)) {
            return Result.fail("请输入手机号");
        }

        mobile = mobile.trim();

        member.setMobile(mobile);
        if (mobile.length() != 11) {
            return Result.fail("手机号错误");
        }

        // 检查手机号是否已注册
        Integer count = memberMapper.selectCount(new LambdaQueryWrapper<Member>().
                eq(Member::getMobile, mobile));
        if (count > 0) {
            log.error("mobile_has_registered,mobile={}", mobile);
            return Result.fail(FailMessage.AUTH_MOBILE_REGISTERED);
        }

        Long id = IdUtil.genSyncMemberId();
        member.setId(id);

        memberMapper.insert(member);
        return Result.ok();
    }

    @Override
    public Result updateById(Member member) {

        String mobile = member.getMobile();
        if (StringTool.isNotEmpty(mobile)) {

            // 更改手机号
            mobile = mobile.trim();
            member.setMobile(mobile);
            if (mobile.length() != 11) {
                return Result.fail("手机号错误");
            }

            // 检查手机号是否已注册
            List<Member> list = memberMapper.selectList(new LambdaQueryWrapper<Member>().
                    eq(Member::getMobile, mobile));

            int size = list.size();
            if (size == 1) {
                // 判断是不是更新会员的手机号
                if (!list.get(0).getId().equals(member.getId())) {
                    return Result.fail("该手机号已存在");
                }
            } else if (size > 1) {
                return Result.fail("系统中已存在多个该手机号");
            }

        }

        //不改手机号
        member.setMobile(null);

        memberMapper.updateById(member);
        return Result.ok();
    }


    @Override
    public Result deleteByIds(Set<Serializable> ids) {

        for (Serializable id : ids) {
            memberMapper.deleteMember(id);
        }
        return Result.ok();
    }

    @Override
    public Result registerLogin(ClientLoginReq req) {

        if (SpringUtil.isProd()) {
            Boolean check = jbbService.smsCheck(req.getMobile(), req.getCode());
            if (!check) {
                return Result.fail("短信验证码不对");
            }
        }

        String password = null;
        try {
            password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, req.getPassword());
            System.out.println(password);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        // 检查手机号是否已注册
        Member member = memberMapper.selectByMobile(req.getMobile());
        if (member != null) {
            return Result.fail(FailMessage.AUTH_MOBILE_REGISTERED);
        }

        Long memberId = IdUtil.genSyncMemberId();

        // 邀请人
        String inviteMobile = null;
        if (!StringUtils.isEmpty(req.getInviteCode())) {
            Long inviteMemberId = InviteCodeUtils.codeToId(req.getInviteCode());
            Member inviter = memberMapper.selectById(inviteMemberId);
            if (inviter != null) {
                MemberInviteLog inviteLog = new MemberInviteLog();
                inviteLog.setMemberId(inviteMemberId);
                inviteLog.setMobile(inviter.getMobile());
                inviteLog.setToMemberId(member.getId());
                inviteLog.setToMobile(req.getMobile());
                memberInviteLogMapper.insert(inviteLog);

                inviteMobile = inviter.getMobile();
            }
        }

        member = new Member();
        member.setId(memberId);
        member.setMobile(req.getMobile());
        member.setPassword(passwordEncoder.encode(password));
        member.setLevel(0);
        member.setStatus(0);
        member.setBalance(0);
        member.setInviteMobile(inviteMobile);
        memberMapper.insert(member);

        insertLoginLog(member.getId(), req.getIp());

        ClientJwt clientJwt = new ClientJwt();
        clientJwt.setMobile(req.getMobile());
        clientJwt.setMemberId(member.getId());
        String clientToken = JwtTokenUtil.createClientToken(clientJwt);
        return Result.ok(clientToken);
    }

    @Override
    public Result<String> clientLogin(ClientLoginReq req) {

        Member member = memberMapper.selectByMobile(req.getMobile());
        if (member == null) {
            return Result.fail("找不到用户");
        }

        if (StringTool.isNotEmpty(req.getCode())) {
            Boolean check = jbbService.smsCheck(req.getMobile(), req.getCode());
            if (!check) {
                return Result.fail("短信验证码不对");
            }
        } else {
            String password = null;
            try {
                password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, req.getPassword());
            } catch (Exception e) {
                log.info("decryptByPrivateKey error", e);
                return Result.fail("密码错误");
            }
            if (!passwordEncoder.matches(password, member.getPassword())) {
                return Result.fail("密码错误");
            }
        }

        if (member.getStatus() == 1) {
            return Result.fail("该账号已被冻结");
        }

//        String upperMobile = jbbService.userUpper(mobile);
//        if (upperMobile != null) {
//            Member update = new Member();
//            update.setId(member.getId());
//            update.setUpperMobile(upperMobile);
//            memberMapper.updateById(update);
//        }

        insertLoginLog(member.getId(), req.getIp());

        ClientJwt clientJwt = new ClientJwt();
        clientJwt.setMobile(req.getMobile());
        clientJwt.setMemberId(member.getId());
        String clientToken = JwtTokenUtil.createClientToken(clientJwt);

        return Result.ok(clientToken);
    }

    private void insertLoginLog(Long memberId, String ip) {
        MemberLoginLog loginLog = new MemberLoginLog();
        loginLog.setMemberId(memberId);
        loginLog.setIp(ip);
        memberLoginLogMapper.insert(loginLog);
    }

    @Override
    public Result resetPassword(Long memberId) {

        Member member = new Member();

        // 默认密码
        String newPwd = passwordEncoder.encode(Constants.DEFAULT_PWD);
        member.setPassword(newPwd);
        member.setId(memberId);
        memberMapper.updateById(member);

        return Result.ok();
    }

    @Override
    public Result updatePassword(UpdatePasswordReq updatePassReq) {

        if (StringUtils.isEmpty(updatePassReq.getNewPwd()) ||
                StringUtils.isEmpty(updatePassReq.getOldPwd())) {
            return Result.fail("密码不能为空");
        }

        String oldPwd = updatePassReq.getOldPwd();
        String newPwd = updatePassReq.getNewPwd();

        String encodeNewPwd = passwordEncoder.encode(newPwd);

        ClientJwt userJwt = Holder.CLIENT_JWT_THREAD_LOCAL.get();
        Long memberId = userJwt.getMemberId();
        Member member = memberMapper.selectById(memberId);

        if (!passwordEncoder.matches(oldPwd, member.getPassword())) {
            return Result.fail("旧密码错误");
        }
        if (passwordEncoder.matches(oldPwd, encodeNewPwd)) {
            return Result.fail("新密码不能与旧密码相同");
        }

        Member update = new Member();
        update.setId(memberId);
        update.setPassword(encodeNewPwd);
        memberMapper.updateById(update);

        return Result.ok();
    }

}